import { BufferAttribute, BufferGeometry, CatmullRomCurve3, Color, Group, Line, LineBasicMaterial, Mesh, Path, Points, SplineCurve } from "three";
import { App } from "../../../../Engine";
import Const from "../../../../application/constants/Const";
import { CustomPointsMaterial } from "../../../../renderExtension/Material/CustomMaterial";
import ShaderConst from "../../../../renderExtension/Material/ShaderConst";
import Events from "../../../../application/constants/Events";
import FlowPoints from "./FlowPoints";
import { Line2 } from "three/examples/jsm/lines/Line2";
import { LineGeometry } from "three/examples/jsm/lines/LineGeometry";
import { LineMaterial } from "three/examples/jsm/lines/LineMaterial";

const defaultTIme = 5000;

export default class FlowLine2 extends Group {
    private app: App;
    public positions = [];
    public startColor;
    public endColor;
    public lineColor;
    private firstPoint;
    private line;
    private startTime = 5000;
    // private spaceIntervals = 100;
    // private pointNum;
    private spaceDistance = 10;
    private narrowLength = 50;
    private periodCount;
    private waitTime;
    private loopMsg: {loopTime: number, sleepTime: number};
    private path:Path;
    private isLoop;
    private isProduct = true;
    // private points;
    // private index = 0;
    // private num = 50;
    // private pointsGeometry: BufferGeometry;
    // private pointsMaterial: CustomPointsMaterial;
    // private flyPoints: Points;

    constructor(cfg: any) {
        super();

        this.app = App.getInstance();
        this.spaceDistance = cfg.spaceDistance ? cfg.spaceDistance : 10;
        this.narrowLength = cfg.narrowLength ? cfg.narrowLength : 50;
        this.waitTime = cfg.waitTime ? cfg.waitTime : 0;
        this.loopMsg = cfg.loopMsg ? cfg.loopMsg : null;
        this.isProduct = (cfg.isProduct == true || cfg.isProduct == undefined) ? true : false;
        // this.pointNum = cfg.pointNum ? cfg.pointNum : 50;

        this.positions = cfg.positions;
        this.positions.forEach(element => {
            element.toEPSGWeb();
        });

        let totalDistance = 0;
        for(let i = 1; i < this.positions.length; i++) {
            totalDistance += this.positions[i].distanceTo(this.positions[i - 1]);
        }
        this.periodCount = totalDistance / this.spaceDistance;

        this.startColor = cfg.startColor ? cfg.startColor : 0x006666;//默认青色
        this.endColor = cfg.endColor ? cfg.endColor : 0xffff00;//默认黄色
        this.lineColor = cfg.lineColor ? cfg.lineColor : 0x006666;//默认青色
        this.startTime = cfg.startTime ? cfg.startTime : 5000;
        this.firstPoint = this.positions[0].clone(); 
        this.makeLine();
        // this.makePoints();
        this.app.on(Events.CameraChange, this.updateLineWidth.bind(this));
    }

    /**
    * 生成线对象
    */
    private makeLine() {
        let self = this;

        var geometry:LineGeometry = new LineGeometry(); //创建一个缓冲类型几何体

        this.positions.forEach(element => {
            element.sub(this.firstPoint);
        });

        this.path = new Path();
        for(let i=0;i<this.positions.length;i++){
            let element = this.positions[i];
            if(i==0){
                this.path.moveTo(element.x, element.y);
            }else{
                this.path.lineTo(element.x, element.y);
                this.path.moveTo(element.x, element.y);
            }
        }
        let points = this.path.getPoints();
        let positions = [];
        points.forEach(element => {
            positions.push(element.x, element.y, 0);
        })
        // setFromPoints方法从points中提取数据赋值给attributes.position
        // geometry.setFromPoints(points);
        geometry.setPositions( positions );
        var material = new LineMaterial({
            color: self.lineColor, //轨迹颜色
            // linewidth: 2,
        });
        // material.resolution.set(window.innerWidth, window.innerHeight); // 设置分辨率
        //线条模型对象
        this.line = new Line2(geometry, material);
        this.line.position.copy(this.firstPoint);
        this.line.computeLineDistances();
        this.updateLineWidth();
        this.add(this.line);

        this.isLoop = (this.loopMsg) ? true : false;
        
        if(this.isProduct){
            let flowoints1 = this.path.getSpacedPoints(this.periodCount); //分段数100，返回101个顶点
            let flowPoints = new FlowPoints(this.startColor, this.endColor, this.firstPoint.clone(), flowoints1, self.spaceDistance, self.narrowLength, self.waitTime, this.isLoop);
            this.add(flowPoints);

            this.app.on(Events.Render, this.productPoints.bind(this));
        }
       
    }

    private executeTime = 0;
    private productPoints() {
        // if(this.isLoop){
        //     let self = this;
        //     for(let i=1; i<=this.loopMsg.loopTime; i++){
        //         setTimeout(() => {
        //                 let flowoints2 = self.path.getSpacedPoints(self.periodCount);
        //                 let flowPoints2 = new FlowPoints(self.startColor, self.endColor, self.firstPoint.clone(), flowoints2, self.spaceDistance, self.narrowLength, self.waitTime, self.isLoop);
        //                 self.add(flowPoints2);
        //             }, i * self.loopMsg.sleepTime);
        //     }

        //     setTimeout(() => {
        //         self.delayGeneratePoints();
        //     }, this.loopMsg.sleepTime * (this.loopMsg.loopTime));
        // }

        if(this.isLoop){
            let self = this;
            if(this.executeTime >= this.loopMsg.sleepTime / 10){
                this.executeTime = 0;
                let flowoints2 = self.path.getSpacedPoints(self.periodCount);
                let flowPoints2 = new FlowPoints(self.startColor, self.endColor, self.firstPoint.clone(), flowoints2, self.spaceDistance, self.narrowLength, self.waitTime, self.isLoop);
                self.add(flowPoints2);
            }

            this.executeTime++;
        }
    }

    private updateLineWidth(){
        let cameraHeight = this.app.camera.position.z;
        let lineWidth = 5000 / cameraHeight;
        if(lineWidth > 5){
            lineWidth = 5;
        }
        if(lineWidth < 1){
            lineWidth = 1;
        }
        this.line.material.linewidth = lineWidth;
    }

}